import 'package:flutter/widgets.dart';
import 'models.dart';
import 'package:todos_repository_core/todos_repository_core.dart';

class StateContainer extends StatefulWidget {
  final AppState? state;
  final Widget child;
  final TodosRepository? repository;
  const StateContainer(
      {required this.child, this.repository, this.state, Key? key})
      : super(key: key);

  @override
  State<StateContainer> createState() => StateContainerState();

  static StateContainerState of(BuildContext context) => context
      .dependOnInheritedWidgetOfExactType<_InheritedStateContainer>()!
      .data;
}

class StateContainerState extends State<StateContainer> {
  AppState? state;
  @override
  void initState() {
    if (widget.state != null) {
      state = widget.state;
    } else {
      state = AppState.loading();
    }
    widget.repository?.loadTodos().then((loadedTodos) {
      setState(() {
        state = AppState(
          todos: loadedTodos.map(Todo.fromEntity).toList(),
        );
      });
    }).catchError((err) {
      setState(() {
        state!.isLoading = false;
      });
    });
    super.initState();
  }

  @override
  void setState(VoidCallback fn) {
    // TODO: implement setState
    super.setState(fn);
    widget.repository
        ?.saveTodos(state!.todos.map((todo) => todo.toEntity()).toList());
  }

  @override
  Widget build(BuildContext context) {
    return _InheritedStateContainer(child: widget.child, data: this);
  }

  void removeTodo(Todo todo) {
    setState(() {
      state!.todos.remove(todo);
    });
  }

  void addTodo(Todo todo) {
    setState(() {
      state!.todos.add(todo);
    });
  }

  void updateTodo(Todo todo,
      {bool? complete, String? id, String? task, String? note}) {
    setState(() {
      todo.complete = complete ?? todo.complete;
      todo.id = id ?? todo.id;
      todo.task = task ?? todo.task;
      todo.note = note ?? todo.note;
    });
  }

  void updateFilter(VisibilityFilter value) {
    setState(() {
      state!.activeFilter = value;
    });
  }

  void toggleAll() {
    setState(() {
      state!.toggleAll();
    });
  }

  void clearCompleted() {
    setState(() {
      state!.clearCompleted();
    });
  }
}

class _InheritedStateContainer extends InheritedWidget {
  final StateContainerState data;
  _InheritedStateContainer(
      {required Widget child, required this.data, Key? key})
      : super(child: child, key: key);

  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) {
    return true;
  }
}
